WR.util.namespace('WR.ui.PhotoWall');

/**
 * Photo-wall toolbar
 *
 * @param {Object} config - config
 * @config {Boolean/Object} autosave - default is true. You may set it to false.
 *                          But you may also configure some autosave params: { timeout: 5000, timeoutStep: 10 }
 */
WR.ui.PhotoWall.Toolbar = function(config) {
    // Pre-process autosave configuration
    this.autosave = $.extend({}, this.autosave);
    this.autosave.toolbar = this;
    // TODO: handle problems with "autosave" object re-construction

    $.extend(true, this, config);

    // Start watching changes
    this.watchChanges();
};

WR.ui.PhotoWall.Toolbar.prototype = {
    // Config params
    dict: {
        HIDE_TOOLBAR: 'Hide toolbar',
        SHOW_TOOLBAR: 'Show toolbar',
        BACK_TO_VIEW: 'Stop editing',
        BACK_TO_EDIT: 'Start editing',
        SAVE_CHANGES: 'Save changes',
        NO_CHANGES: 'Nothing to save',
        SAVING_NOW: 'Saving...'
    },

    autosave: true, // look true definition further in this class
    watchChangesInterval: 1000,

    template: new WR.util.Template(
        '<div class="wr-photo-wall-toolbar">' +
            // Active toolbar
            '<div class="wr-active-toolbar">' +
                // "Hide toolbar" button
                '<a href="#hide-toolbar" class="wr-button wr-hide-button" title="{{ HIDE_TOOLBAR }}">' +
                    '<span class="wr-icon"></span>' +
                '</a>' +

                // "Stop edit and go to user view" button
                '<a href="#stop-edit" class="wr-button wr-cancel-edit-button" title="{{ BACK_TO_VIEW }}">' +
                    '<span class="wr-icon"></span><span>{{ BACK_TO_VIEW }}</span>' +
                '</a>' +

                // "Save" button
                '<a href="#save-wall" class="wr-button wr-save-button wr-save-button-disabled" title="{{ SAVE_CHANGES }}">' +
                    '<span class="wr-icon"></span>' +
                    '<span class="wr-save-changes" style="display:none;">' +
                        '{{ SAVE_CHANGES }}' +
                        '<div class="wr-tiny-progress-bar"></div>' +
                    '</span>' +
                    '<span class="wr-no-changes">{{ NO_CHANGES }}</span>' +
                    '<span class="wr-saving-now" style="display:none;">{{ SAVING_NOW }}</span>' +
                '</a>' +

                // Zooming buttons
                '<a href="#zoom-wall" class="wr-button wr-zoom-button wr-zoom-out-button" title="10%">' +
                    '<span class="wr-icon"></span>' +
                    '<span class="wr-zoom-value wr-zoom-value-10">10%</span>' +
                '</a>' +
                '<a href="#zoom-wall" class="wr-button wr-zoom-button" title="25%">' +
                    '<span class="wr-zoom-value wr-zoom-value-25">25%</span>' +
                '</a>' +
                '<a href="#zoom-wall" class="wr-button wr-zoom-button" title="50%">' +
                    '<span class="wr-zoom-value wr-zoom-value-50">50%</span>' +
                '</a>' +
                '<a href="#zoom-wall" class="wr-button wr-zoom-button wr-zoom-in-button" title="100%">' +
                    '<span class="wr-zoom-value wr-zoom-value-100">100%</span>' +
                    '<span class="wr-icon"></span>' +
                '</a>' +
            '</div>' +

            // Passive toolbar
            '<div class="wr-passive-toolbar">' +
                // "Show toolbar" button
                '<a href="#show-toolbar" class="wr-button wr-show-button" title="{{ SHOW_TOOLBAR }}">' +
                    '<span class="wr-icon"></span>' +
                '</a>' +

                // "Continue edit" button
                '<a href="#start-edit" class="wr-button wr-start-edit-button" title="{{ BACK_TO_EDIT }}">' +
                    '<span class="wr-icon"></span>' +
                '</a>' +
            '</div>' +
        '</div>'
    ),

    // Private params
    el: null,
    wall: null,
    rendered: false,
    saveButton: null,

    render: function() {
        if (this.wall && !this.rendered) {
            this.el = $(this.template.apply(this.dict)).prependTo(this.wall.container);

            // Attach show/hide handlers
            var self = this,
                toggleBar = function(e) { e.preventDefault(); self.toggleToolbar(); },
                toggleEdit = function(e) { e.preventDefault(); self.toggleToolbar(true); };
            this.el.find('.wr-hide-button, .wr-show-button').click(toggleBar);
            this.el.find('.wr-cancel-edit-button, .wr-start-edit-button').click(toggleEdit);

            this.saveButton = this.el.find('.wr-save-button');
            this.saveButton.click(function(e) {
                e.preventDefault();
                self.saveChanges();
            });

            this.el.find('.wr-passive-toolbar').draggable({ axis: 'x', distance: 10 });

            // Init zoom
            this.el.find('.wr-zoom-button').each(function() {
                var val = parseInt($(this).find('.wr-zoom-value').text()) / 100;
                $(this).click(function(e) {
                    e.preventDefault();
                    self.wall.setZoom(val);
                });
            });

            this.rendered = true;
        }
    },

    /**
     * Toggle toolbar modes: edit or view
     *
     * @param {Boolean} switchEditable - switch editable mode or not? Default: false
     */
    toggleToolbar: function(switchEditable) {
        if (!this.rendered)
            return;

        var act = this.el.find('.wr-active-toolbar'),
            pas = this.el.find('.wr-passive-toolbar');

        if (act.is(':visible')) {
            act.stop(true, true).hide();
            pas.stop(true, true).hide();

            if (switchEditable) {
                pas.find('.wr-show-button').hide().end().find('.wr-start-edit-button').show();

                // Stop watching for changes and cancel autosaving
                this.unwatchChanges();
                this.autosave.stop();

                // Stop edit the wall and show User View
                this.wall.setEditable(false, "I demand you to keep toolbar visible!");
            } else {
                pas.find('.wr-start-edit-button').hide().end().find('.wr-show-button').show();
            }

            act.slideUp();
            // PNG BG with gradient-transparency has some problems with opacity in the IE
            pas[$.browser.msie ? 'show' : 'fadeIn']();
        } else {
            act.stop(true, true).hide();
            pas.stop(true, true).hide();

            act.slideDown();
            // PNG BG with gradient-transparency has some problems with opacity in the IE
            pas[$.browser.msie ? 'hide' : 'fadeOut']();

            if (switchEditable) {
                // Start edit the wall
                this.wall.setEditable(true);

                // Start watching for changes
                this.watchChanges();
            }
        }
    },

    watchChangesIntervalId: null,

    watchChanges: function() {
        this.unwatchChanges();
        this.watchChangesIntervalId = setInterval($.proxy(this, 'watchChangesIteration'), this.watchChangesInterval);
    },

    watchChangesIteration: function() {
        if (!this.rendered)
            return;
		
		if (this.wall) {
            if (this.wall.changed && !this.wall.saving) {
                this.saveButton.removeClass('wr-save-button-disabled')
                    .find('.wr-no-changes, .wr-saving-now').hide().end()
                    .find('.wr-save-changes').show();

                if (this.autosave && this.autosave.timeLeft <= 0)
                    this.autosave.start();
            } else {
                this.saveButton.addClass('wr-save-button-disabled')
                    .find('.wr-save-changes, .wr-saving-now, .wr-no-changes').hide();

                if (this.wall.saving)
                    this.saveButton.find('.wr-saving-now').show();
                else
                    this.saveButton.find('.wr-no-changes').show();
            }
        }
    },

    unwatchChanges: function() {
        clearInterval(this.watchChangesIntervalId);
    },

    saveChanges: function() {
        if (this.wall.saving || !this.wall.changed)
            return;

        this.wall.saveChanges();
        this.watchChangesIteration();
    },

    // Singletone in some sense.
    // I don't want (for now) to separate this into class
    autosave: {
        timeout: 30000,     // may be configured somehow
        timeoutStep: 100,   // may be configured somehow
        timeLeft: null,     // inited in method
        timeoutId: null,    // inited in method
        progressBar: null,  // inited in method
        toolbar: null,      // inited in constructor

        start: function() {
            this.stop();

            if (!this.progressBar)
                this.progressBar = this.toolbar.saveButton.find('.wr-tiny-progress-bar');

            this.progressBar.show();

            this.timeLeft = this.timeout;
            this.timeoutId = setTimeout($.proxy(this, 'iteration'), this.timeoutStep);
        },

        stop: function() {
            clearTimeout(this.timeoutId);
            this.timeLeft = null;

            if (this.progressBar)
                this.progressBar.hide();
        },

        iteration: function() {
            this.progressBar.width(Math.ceil(this.timeLeft * 100 / this.timeout) + '%');
            this.timeLeft -= this.timeoutStep;
            if (this.timeLeft <= 0) {
                this.toolbar.saveChanges();
                this.stop();
            } else {
                this.timeoutId = setTimeout($.proxy(this, 'iteration'), this.timeoutStep);
            }
        }
    }
};
